iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 4
0
Software Development

iOS 從 Objective-c 進化為 Swift 的 30天之旅系列 第 4

[Day 4] iOS userdefaults 分別存 VS 存在同一個NSArray 速度比較

  • 分享至 

  • xImage
  •  

儲存方式

前言

iOS 儲存方式有很多
例如

  1. NSUserDefaults
  2. plist
  3. archiving (封存)
  4. SQLite
  5. Core Data

以上我除了archiving沒用過
其他都有練習過了
但比較順手的應該是
NSUserDefaults
較簡單好用
如果MySQL熟悉的話
SQLite 就你的首選

資料儲存速度疑問?

記帳本每日都需紀錄
如果都存在同一個Array
此時需要查詢某一天
那提取UserDefaults時
就會拉回整個Array 在找尋日期key值
問題來了
如果我分開儲存 提取會比較快嗎
比如每個日期都單獨存在UserDefaults
不用Array
這樣在提取的時候就不用提取所有資料
真的會這麼順利嗎?速度會比較快嗎?

測試軟體使用OC寫比較快
單純比較

前置作業

實驗組A 存在Array 1萬筆

    //摻在一起做撒尿牛丸
    NSMutableArray * arrayA = [[NSMutableArray alloc] init];
    for (int i = 0; i<10000; i++) {
        //[arrayA setValue:@"這是五個字" forKey:[[NSString alloc]initWithFormat:@"arrayA_%d",i]];
        [arrayA addObject:@"這是五個字"];
    }
    [_standardUserDefaults setObject:arrayA forKey:@"arrayA"];

實驗組B 分別存 1萬筆

    //分散儲存
    NSMutableArray * arrayB = [[NSMutableArray alloc] init];
    for (int i = 0; i<10000; i++) {
        [arrayB addObject:@"這是五個字"];
        [_standardUserDefaults setObject:@"這是五個字" forKey:[[NSString alloc]initWithFormat:@"arrayB_%d",i]];
    }

接下來執行讀取一萬筆並且打印出來
模擬對資料的運用

讀取計時

實驗組A

- (IBAction)clickTogetherBtn:(id)sender {
    togetherTime = 0;
    userDefaultTimer = [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:@selector(updateTimeA:) userInfo:nil repeats:YES];
    
    if (_standardUserDefaults == nil) {
        _standardUserDefaults = [NSUserDefaults standardUserDefaults];
    }
    NSMutableArray * array = [[NSMutableArray alloc] init];
    array = [_standardUserDefaults objectForKey:@"arrayA"];
    
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_async(group, queue, ^{
        for (int i=0; i<10000; i++) {
            NSLog(@"%@",[array objectAtIndex:i]);
            dispatch_async(dispatch_get_main_queue(), ^{
                self->_togetherCountLabel.text = [[NSString alloc] initWithFormat:@"%d",i+1];
            });
            if (i == 10000-1) {
                [self->userDefaultTimer invalidate];
                self->userDefaultTimer = nil;
                break;
                
            }
        }
    });
    dispatch_group_notify(group, queue, ^{
        NSLog(@"done");
    });
}

取出Array 就開始打印
並且計時以0.001為一個計數單位

實驗組B

- (IBAction)clickSingleBtn:(id)sender {
    singleTime = 0;
    userDefaultTimer = [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:@selector(updateTimeB:) userInfo:nil repeats:YES];
    
    if (_standardUserDefaults == nil) {
        _standardUserDefaults = [NSUserDefaults standardUserDefaults];
    }
    NSMutableArray * array = [[NSMutableArray alloc] init];
    array = [_standardUserDefaults objectForKey:@"arrayB"];
    
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_async(group, queue, ^{
        for (int i=0; i<10000; i++) {
            NSLog(@"%@",[self->_standardUserDefaults objectForKey:[[NSString alloc]initWithFormat:@"arrayB_%d",i]]);
            dispatch_async(dispatch_get_main_queue(), ^{
                self->_singleCountLabel.text = [[NSString alloc] initWithFormat:@"%d",i+1];
            });
            if (i == 10000-1) {
                [self->userDefaultTimer invalidate];
                self->userDefaultTimer = nil;
                break;
                
            }
        }
    });
    dispatch_group_notify(group, queue, ^{
        NSLog(@"done");
    });
}

直接尋找這1萬筆
並且打印

結果輸出


結果出乎我意料
其實存在Array比單獨的快
數量為1萬筆 平均差距為0.2秒
可能原因是UserDefaults收尋較耗時

另外也有單獨測試
單一UserDefaults收尋 VS Array for key
一樣是1萬筆取1
基本上不分上下都是0.005秒以下
所以應該不用比較 都很快

結論

直接存成Array在存在UserDefaults就可以了
經過1萬筆資料測試獲勝
雖然只有0.2秒 但是如果資料量超多
差距就會慢慢出現
在改就會有點麻煩

平時想東想西的
還是實際測試比較心安一點
就這樣 如果我是錯誤的
麻煩在糾正我
說不定是我程式寫歪也說不定

最新文章

金魚也學得會的「KD指標」! 什麼是KD黃金交叉、KD死亡交叉 - 2021年

RSI指標? 看我就好 新手好入門


上一篇
[Day 3] Swift TableView 與 客製化cell設計
下一篇
[Day 5] 重新規劃架構
系列文
iOS 從 Objective-c 進化為 Swift 的 30天之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
jason0shi
iT邦新手 5 級 ‧ 2019-09-03 16:33:23

不是很明白你這樣做的理由,但是我的做法會把這一萬筆在近前景畫面的時候讀出來,
放在singleton的一個property裡面處理近背景後或儲存的時候在存回去plist,
提供一個作法給你參考。

這是我之前寫資料庫時會碰到的問題
把大多數的資料都存在同一個 table
時間久了會造成select效率變慢
做關聯是資料表才是長久之計

所以此篇只是想試試看能不能像SQL一樣
建立主表與動態表
這項關聯式資料的架構下
是否會比較快速

我要留言

立即登入留言